/*///global files
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>

#include "snake.h"

using namespace std;

int main (int argc, char** argv) {
	cin.get();
	return 0;
}

*/

#define M_PI 3.14159

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/types_c.h>
#include <iostream>
#include <fstream>
#include <cmath>

//#include <Windows.h>
#include <thread>

#include "mat_utils.h"
#include "GVFField.h"
#include "snake.h"

using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
	//Compute GVF and save to file
	//image_path, method, iterations, mu, (optional)del_t factor 1/(->x*mu)
	if (argc == 5 || argc == 6) {
		cout << "C++ GVF" << endl;
		string img(argv[1]);
		int method = atoi(argv[2]);
		int iter = atoi(argv[3]);
		double mu = atof(argv[4]);

		GVFField::grad_method grad;
		switch (method) {
		//0 case
		case GVFField::SCHARR_METHOD :
			grad = GVFField::SCHARR_METHOD;
			break;
		//1 case
		case GVFField::SOBEL_METHOD:
			grad = GVFField::SOBEL_METHOD;
			break;
		default:
			grad = GVFField::SOBEL_METHOD;
			break;
		}

		GVFField *pgvf;
		if (argc == 6) {
			double factor = atof(argv[5]);
			pgvf = new GVFField(img, grad, iter, mu, factor);
		}
		else {
			pgvf = new GVFField(img, grad, iter, mu);

		}
		GVFField gvf = *pgvf;

		gvf.normalize();

		// testing the pipe operator portion of the GVF
		ofstream gvffile;
		gvffile.open("gvf.dat", ios::out);
		gvffile << gvf;
		gvffile.close();
	}
	//deform snake and save to file
	//iterations, radius, alpha, beta, kappa, gamma
	else if (argc == 9) {
		cout << "C++ SNAKE" << endl;
		//TODO change input to use argv
		GVFField gvf("gvf.dat");
		
		//int radius = gvf.u.rows / 4;//midx < midy ? midx-5: midy-5;
		ofstream snakefile;
		snakefile.open("snake.dat", ios::out);
		
		int iter = atoi(argv[1]);
		double radius = atof(argv[2]);
		double alpha = atof(argv[3]);
		double beta = atof(argv[4]);
		double kappa = atof(argv[5]);
		double gamma = atof(argv[6]);
		double mindist = atof(argv[7]);
		double maxdist = atof(argv[8]);

		Snake sn = Snake(radius, snakefile, gvf, alpha, beta, kappa, gamma, mindist, maxdist);
		sn.deformSnake(iter);

		snakefile.close();

	}
	//Bilateral Filter option
	else if (argc == 4) {
		cout << "4!" << endl;
		int d = atoi(argv[2]);
		double sigmaspace = atof(argv[3]);
		Mat src = imread(argv[1]);
		imgData *id = new imgData("base image", src);
		Mat dst;
		cv::bilateralFilter(src, dst, d, sigmaspace, sigmaspace);
		string fname = string(argv[1]) + "filter.png";
		imwrite(fname, dst);
	}
	//just run the test case
	else {
		cout << "C++ ELSE" << endl;
		//string imgloc = R"(C:\Users\nsmith\Dropbox\1Research\Snake Project\Snake_Interface\testcell.png)";
		GVFField gvf = GVFField("room.pgm", GVFField::STORED_GVF);
		gvf.normalize();

		// testing the pipe operator portion of the GVF
		ofstream gvffile;
		gvffile.open("gvf.dat", ios::out);
		gvffile << gvf;
		gvffile.close();

		int radius = gvf.u.rows / 4;//midx < midy ? midx-5: midy-5;

		//TODO change snakefile to a user-specified file location (or TEMP dir)
		ofstream snakefile;
		snakefile.open("snake.dat", ios::out);

		Snake sn = Snake(radius, snakefile, gvf);
		sn.deformSnake(81);

		snakefile.close();
	}

	return 0;
}